#ifndef NANE_FILESYSTEM_H
#   define  NANE_FILESYSTEM_H

#   include "nane/core/IFileSystem.h"
#   include "nane/core/IntrusivePtr.h"
#   include "nane/core/Holder.h"
#   include "nane/core/assert.h"
#   include "nane/core/crt/Context.h"

namespace nane
{
    template<class S>
    class FileSystemHolder
        : public Holder<S>
    {
    };
    
    template<>
    class FileSystemHolder<IFileSystem>
        : public Holder<IFileSystem>
    {
    public:
        static IFileSystem* Instance()
        {
            if( s_instance == NULL )
            {
                s_instance = nane::m_context->fileSystem;
            }
            return s_instance;            
        }
    };
    
    typedef IntrusivePtr<IInputRef> InputPtr;
    typedef IntrusivePtr<IOutputRef> OutputPtr;
    typedef IntrusivePtr<IInputSeekableRef> InputSeekablePtr;
    typedef IntrusivePtr<IOutputSeekableRef> OutputSeekablePtr;
    typedef IntrusivePtr<IReadFile> ReadFilePtr;
    typedef IntrusivePtr<IWriteFile> WriteFilePtr;
    
    class FileSystem
    {
    public:
        static bool Initialize();
        static void Shutdown();

        static ReadFilePtr OpenReadFile( const char* _filename )
        {
            NANE_ASSERT_RV( _filename != NULL, "filename must be valid", NullPtr );
            IReadFile* fileInterface = FileSystemHolder<IFileSystem>::Instance()->OpenReadFile(_filename);
            return ReadFilePtr(fileInterface);
        }
        
        static WriteFilePtr OpenWriteFile( const char* _filename )
        {
            NANE_ASSERT_RV( _filename != NULL, "filename must be valid", NullPtr );
            IWriteFile* fileInterface = FileSystemHolder<IFileSystem>::Instance()->OpenWriteFile(_filename);
            return WriteFilePtr(fileInterface);
        }
        
        static bool Exists( const char* _filename )
        {
            NANE_ASSERT_RV( _filename != NULL, "filename must be valid", false );
            return FileSystemHolder<IFileSystem>::Instance()->Exists(_filename);
        }
        
        static bool DeleteFile( const char* _filename )
        {
            NANE_ASSERT_RV( _filename != NULL, "filename must be valid", false );
            return FileSystemHolder<IFileSystem>::Instance()->DeleteFile(_filename);
        }
        
        static bool CreateFolder( const char* _path )
        {
            NANE_ASSERT_RV( _path != NULL, "path must be valid", false );
            return FileSystemHolder<IFileSystem>::Instance()->CreateFolder(_path);
        }
        
        static bool DeleteFolder( const char* _path )
        {
            NANE_ASSERT_RV( _path != NULL, "path must be valid", false );
            return FileSystemHolder<IFileSystem>::Instance()->DeleteFolder(_path);
        }
        
    public:
        class Implementation;
    };
    
} // namespace nane

#endif	// NANE_FILESYSTEM_H
